
#include "taic_base_data.h"

using namespace datasets_taic;

// [*] datasets_taic::CSourceItem

datasets_taic::CSourceItem::CSourceItem()
{
	myInit(-1, -1, -1, -1);
}

datasets_taic::CSourceItem::CSourceItem( int Label, int WordIndex, int HiddenRank, int SingleFeatureValue )
{
	myInit(Label, WordIndex, HiddenRank, SingleFeatureValue);
}

void datasets_taic::CSourceItem::myInit( int Label, int WordIndex, int HiddenRank, int SingleFeatureValue )
{
	this->Label = Label;
	this->WordIndex = WordIndex;
	this->HiddenRank = HiddenRank;
	FeatureList.Clear();
	FeatureList.PushBack(SingleFeatureValue, 0.0);
	this->InstanceAmount = 0;
}

bool datasets_taic::CSourceItem::operator<( const CSourceItem& Another ) const
{
	if (Label != Another.Label) return Label < Another.Label;
	if (WordIndex != Another.WordIndex) return WordIndex < Another.WordIndex;
	if (HiddenRank != Another.HiddenRank) return HiddenRank < Another.HiddenRank;
	return false;
}

int datasets_taic::CSourceItem::ComputeInstanceAmount()
{
	InstanceAmount = 0;
	int i;
	for ( i = 0; i < FeatureList.Length; ++i )
		InstanceAmount += CMyMath::TranslateNumber_Round(FeatureList.ValueList.pElement[i], (int)0);
	return InstanceAmount;
}

// [*] datasets_taic::CSourceFeatureCountDataSet

datasets_taic::CSourceFeatureCountDataSet::CSourceFeatureCountDataSet()
{
	Clear();
}

void datasets_taic::CSourceFeatureCountDataSet::Clear()
{
	Size_C = Size_F = 0;
	Size_W = 0;
	//Size_V = Size_X = 0;
	List_Item.Clear();
	ListWC_P_w_given_c_D.Clear();
}

void datasets_taic::CSourceFeatureCountDataSet::myInit( string strFN_Data_WD, string strFN_Data_FWV )
{
	Clear();
	CSimpleTypeArray<int> mapSrcWordIndex;
	mapSrcWordIndex.Clear();
	// Process word2image
	{
		ifstream inFile_WD(strFN_Data_WD.c_str());
		int tc, tw;
		double tp;
		inFile_WD>>Size_C>>Size_W;
		ListWC_P_w_given_c_D.Resize(Size_W * Size_C);
		ListWC_P_w_given_c_D.Fill(0.0);
		mapSrcWordIndex.Resize(Size_W * Size_C);
		mapSrcWordIndex.Fill(-1);

		while (inFile_WD>>tc>>tw>>tp)
		{
			if (tc<0 || tc>=Size_C) continue;
			if (tw<0 || tw>=Size_W) continue;
			ListWC_P_w_given_c_D.pElement[tw + tc * Size_W] = tp;
		}
		inFile_WD.close();
		inFile_WD.clear();

		CSimpleTypeArray<CIVPair> ivpList;
		CIVPair tIVP;
		for ( tc = 0; tc < Size_C; ++tc )
		{
			ivpList.Clear();
			for ( tw = 0; tw < Size_W; ++tw )
			{
				tIVP.myInit(tw, 0.0 - ListWC_P_w_given_c_D.pElement[tw + tc * Size_W]);
				ivpList.PushBack(tIVP);
			}
			sort(ivpList.Begin(), ivpList.End(), CIVPair::CompareByValue);
			for ( tw = 0; tw < Size_W; ++tw )
			{
				tIVP = ivpList.pElement[tw];
				ListWC_P_w_given_c_D.pElement[tw + tc * Size_W] = 0.0 - tIVP.Value;
				mapSrcWordIndex.pElement[tIVP.Index + tc * Size_W] = tw;
			}
		}

	}
	// Process svmCorpus
	{
		char op;
		double fv;
		int i, hr, ll, lw, fi;
		char strTemp[1000001];
		int tsx;

		Size_F = 0;
		ifstream inFile_FWV(strFN_Data_FWV.c_str());
		inFile_FWV>>tsx>>i;
		List_Item.Resize(tsx);
		ll = lw = -1;
		for ( i = 0; i < tsx; ++i )
		{
			CSourceItem& tItem = List_Item.pElement[i];
			inFile_FWV>>tItem.Label>>tItem.WordIndex;
			if (tItem.Label >= Size_C)
			{
				tItem.Label -= Size_C;
				tItem.WordIndex = -1;
			}

			if (tItem.WordIndex >= 0)
				tItem.WordIndex = mapSrcWordIndex.pElement[tItem.WordIndex + tItem.Label * Size_W];

			if (tItem.Label!=ll || tItem.WordIndex!=lw) hr = 0;
			tItem.myInit(tItem.Label,  tItem.WordIndex, hr++, i);
			ll = tItem.Label; lw = tItem.WordIndex;
			CSparseVector& tSV = tItem.FeatureList;
			tSV.Clear();
			inFile_FWV.getline(strTemp, 1000000);
			istringstream iss(strTemp);
			while (iss>>fi>>op>>fv)
			{
				if (fi > Size_F) Size_F = fi;
				tSV.PushBack(--fi, fv);
			}
			tItem.ComputeInstanceAmount();
		}
		this->SortItemList();
		inFile_FWV.close();
		inFile_FWV.clear();
	}
}

void datasets_taic::CSourceFeatureCountDataSet::SortItemList()
{
	int i;
	int N = (int)List_Item.Size;

	CSimpleTypeArray<CSparseVector> SV_List;
	SV_List.Resize(N);
	for ( i = 0; i < N; ++i )
	{
		CSourceItem& tItem = List_Item.pElement[i];
		CSparseVector& tSV = SV_List.pElement[i];
		tSV.Clear(); tSV.PushBack(i, 0.0);
		tItem.FeatureList.Swap(tSV);
	}
	sort(List_Item.Begin(), List_Item.End());
	for ( i = 0; i < N; ++i )
	{
		CSourceItem& tItem = List_Item.pElement[i];
		CSparseVector& tSV = SV_List.pElement[tItem.FeatureList.IndexList.pElement[0]];
		tItem.FeatureList.Swap(tSV);
		//tItem.ComputeInstanceAmount();
	}
}

void datasets_taic::CSourceFeatureCountDataSet::MakeFullImageExampleList(
	CWeightedClassificationExampleList& DstExampleList, bool fClearFirst,
	int MinWordIndexAllowed, int MaxWordIndexAllowed, int K) const
{
	int i_label;
	if (fClearFirst) DstExampleList.Clear();
	for ( i_label = 0; i_label < Size_C; ++i_label )
		MakeSingleClassImageExampleList(i_label, DstExampleList, false, MinWordIndexAllowed, MaxWordIndexAllowed, K);
}

void datasets_taic::CSourceFeatureCountDataSet::MakeSingleClassImageExampleList(
	int Label, CWeightedClassificationExampleList& DstExampleList, bool fClearFirst,
	int MinWordIndexAllowed, int MaxWordIndexAllowed, int K) const
{
	if (fClearFirst) DstExampleList.Clear();
	int i;
	int o, o1, o2;
	for ( i = MinWordIndexAllowed; i <= MaxWordIndexAllowed; ++i )
	{
		o1 = this->LowerBound(Label, i);
		o2 = this->UpperBound(Label, i);
		if (i>=0 && o2-o1>K) o2 = o1+K;
		for ( o = o1; o < o2; ++o )
			DstExampleList.PushBack(o, 1.0);
	}
}

double datasets_taic::CSourceFeatureCountDataSet::GetP_w_given_c_D( int WordIndex, int Label ) const
{
	if (WordIndex<0 || WordIndex>=Size_W) return MINIMUM_DOUBLE_EPS_V;
	if (Label<0 || Label>=Size_C) return MINIMUM_DOUBLE_EPS_V;
	return ListWC_P_w_given_c_D.pElement[WordIndex + Label * Size_W];
}

int datasets_taic::CSourceFeatureCountDataSet::LowerBound( int Label, int WordIndex, int HiddenRank ) const
{
	static CSourceItem tItem;
	tItem.myInit(Label, WordIndex, HiddenRank, 0);
	return (int)(lower_bound(List_Item.Begin(), List_Item.End(), tItem) - List_Item.Begin());
}

int datasets_taic::CSourceFeatureCountDataSet::UpperBound( int Label, int WordIndex, int HiddenRank ) const
{
	static CSourceItem tItem;
	tItem.myInit(Label, WordIndex, HiddenRank, 0);
	return (int)(upper_bound(List_Item.Begin(), List_Item.End(), tItem) - List_Item.Begin());
}

void datasets_taic::CSourceFeatureCountDataSet::InitAndClearPureImageDataSet( int Size_C, int Size_F )
{
	this->Clear();
	this->Size_C = Size_C;
	this->Size_F = Size_F;
	List_Item.Clear();
}

void datasets_taic::CSourceFeatureCountDataSet::PushBackItem(
	const CSourceFeatureCountDataSet* pSrcFCDS, int ItemIndex,
	int Label, int WordIndex, int HiddenRank )
{
	if (pSrcFCDS == NULL) return;
	if (ItemIndex<0 || ItemIndex>=(int)pSrcFCDS->List_Item.Size) return;
	CSourceItem tItem;
	tItem = pSrcFCDS->List_Item.pElement[ItemIndex];
	tItem.Label = Label;
	tItem.WordIndex = WordIndex;
	tItem.HiddenRank = HiddenRank;
	List_Item.PushBack(tItem);
}

// [*] datasets_taic::C_FCDS_LabeledDataSetForClassification

void datasets_taic::C_FCDS_LabeledDataSetForClassification::myInit( const CSourceFeatureCountDataSet* pFCDS )
{
	this->pFCDS = pFCDS;
}

int datasets_taic::C_FCDS_LabeledDataSetForClassification::GetExampleLabel( int ExampleIndex )
{
	if (pFCDS==NULL || ExampleIndex<0 || ExampleIndex>=(int)pFCDS->List_Item.Size) return 0;
	return pFCDS->List_Item.pElement[ExampleIndex].Label;
}

int datasets_taic::C_FCDS_LabeledDataSetForClassification::GetExampleAmount()
{
	if (pFCDS==NULL) return 0;
	return (int)pFCDS->List_Item.Size;
}

double datasets_taic::C_FCDS_LabeledDataSetForClassification::GetExampleInitialWeight( int ExampleIndex )
{
	if (pFCDS==NULL || ExampleIndex<0 || ExampleIndex>=(int)pFCDS->List_Item.Size) return 0.0;
	return 1.0;
}

int datasets_taic::C_FCDS_LabeledDataSetForClassification::GetFeatureDimension()
{
	if (pFCDS==NULL) return 0;
	return pFCDS->Size_F;
}

double datasets_taic::C_FCDS_LabeledDataSetForClassification::GetExampleFeature( int ExampleIndex, int FeatureIndex )
{
	if (pFCDS==NULL || ExampleIndex<0 || ExampleIndex>=(int)pFCDS->List_Item.Size) return 0.0;
	if (FeatureIndex<0 || FeatureIndex>=pFCDS->Size_F) return 0.0;
	return pFCDS->List_Item.pElement[ExampleIndex].FeatureList.GetValue(FeatureIndex);
}

// [*] datasets_taic::CClassInformation

// [*] datasets_taic::CClassDataSet

void datasets_taic::CClassDataSet::myInit(string strFN_ClassLabel)
{
	CClassInformation tClassInfo;

	ifstream inFile(strFN_ClassLabel.c_str());
	getline(inFile, strName);
	getline(inFile, strPN_Base);
	getline(inFile, strFN_Data_WD);
	getline(inFile, strFN_Data_FWV);
	ClassAmount = 0;
	List_ClassInfo.Clear();
	mapClassName.clear();
	tClassInfo.FCDS_Index = -1;
	while (inFile>>tClassInfo.strFCDS>>tClassInfo.In_FCDS_Label>>tClassInfo.strName)
	{
		List_ClassInfo.PushBack(tClassInfo);
		mapClassName[tClassInfo.strName] = ClassAmount;
		++ClassAmount;
	}
	List_FCDS.DeepClear();
	List_FCDS.Resize(mapClassName.size());
	List_FCDS.Clear();
}

int datasets_taic::CClassDataSet::LoadFCDS(int ClassIndex)
{
	if (ClassIndex<0 || ClassIndex>=ClassAmount) return -1;
	CClassInformation& tClassInfo = List_ClassInfo.pElement[ClassIndex];

	int p = List_ClassInfo.pElement[ClassIndex].FCDS_Index;
	if (p >= 0) return p;

	p = (int)List_FCDS.Size;
	tClassInfo.FCDS_Index = p;
	List_FCDS.Resize(p+1);

	char strTemp[10001];
	string t_strFN_Data_WD;
	string t_strFN_Data_FWV;
	sprintf_s(strTemp, "%s%s\\%s",
		this->strPN_Base.c_str(),
		tClassInfo.strFCDS.c_str(),
		this->strFN_Data_WD.c_str());
	t_strFN_Data_WD = strTemp;
	sprintf_s(strTemp, "%s%s\\%s",
		this->strPN_Base.c_str(),
		tClassInfo.strFCDS.c_str(),
		this->strFN_Data_FWV.c_str());
	t_strFN_Data_FWV = strTemp;

	CSourceFeatureCountDataSet& tFCDS = List_FCDS.pElement[p];
	tFCDS.myInit(t_strFN_Data_WD, t_strFN_Data_FWV);
	return p;
}

int datasets_taic::CClassDataSet::GetClassIndex( string strClassName ) const
{
	map<string, int>::const_iterator itr = mapClassName.find(strClassName);
	if (itr == mapClassName.end()) return -1;
	return itr->second;
}

const CSourceFeatureCountDataSet* datasets_taic::CClassDataSet::GetPtrFCDS( int ClassIndex )
{
	if (ClassIndex<0 || ClassIndex>=ClassAmount) return NULL;
	int p = LoadFCDS(ClassIndex);
	return List_FCDS.pElement + p;
}

const CSourceFeatureCountDataSet* datasets_taic::CClassDataSet::GetPtrFCDS( string strClassName )
{
	return GetPtrFCDS(GetClassIndex(strClassName));
}

// [*] datasets_taic::CSingleClassNaiveBayesModel_TAIC

datasets_taic::CSingleClassNaiveBayesModel_TAIC::CSingleClassNaiveBayesModel_TAIC()
{
	Clear();
}

void datasets_taic::CSingleClassNaiveBayesModel_TAIC::Clear()
{
	FeatureDimension = 0;
	vecF_logP_f_given_c_L.Clear();
	vecF_P_f_given_c_V.Clear();
	vecF_P_f_given_c_D.Clear();

	SelectTopK = WordDimension = 0;
	Lambda = 0.0;
	vecW_P_w_given_c_D.Clear();
	matFW_P_f_given_w_c.Clear();
}

void datasets_taic::CSingleClassNaiveBayesModel_TAIC::InitFeatureDimension( int FeatureDimension )
{
	this->FeatureDimension = FeatureDimension;
	vecF_logP_f_given_c_L.Resize(FeatureDimension);
	vecF_P_f_given_c_V.Resize(FeatureDimension);
	vecF_P_f_given_c_D.Resize(FeatureDimension);
}

void datasets_taic::CSingleClassNaiveBayesModel_TAIC::InitImageModel(
	const CSourceFeatureCountDataSet* pSrcFCDS, int Label,
	CWeightedClassificationExampleList& TrainImageExampleList,
	int MinWordIndexAllowed, int MaxWordIndexAllowed, int K)
{
	if (pSrcFCDS == NULL) return;
	if (Label<0 || Label>=pSrcFCDS->Size_C) return;
	InitFeatureDimension(pSrcFCDS->Size_F);

	int i_Example, i_PtrFeature, i_FeatureIndex;
	double tInstanceAmount;

	CWeightedClassificationExampleList FilteredImageExampleList;
	FilteredImageExampleList.Clear();
	for ( i_Example = 0; i_Example < TrainImageExampleList.ExampleAmount; ++i_Example )
	{
		CWeightedClassificationExample& tExample = TrainImageExampleList.rgExample[i_Example];
		CSourceItem& tItem = pSrcFCDS->List_Item.pElement[tExample.ExampleIndex];
		if (tItem.Label != Label) continue;
		if (tItem.WordIndex < MinWordIndexAllowed) continue;
		if (tItem.WordIndex > MaxWordIndexAllowed) continue;
		if (tItem.WordIndex>=0 && tItem.HiddenRank>=K) continue;

		FilteredImageExampleList.PushBack(tExample);
	}
	if (FilteredImageExampleList.TotalExampleWeight < MINIMUM_DOUBLE_EPS_C)
	{
		vecF_P_f_given_c_V.Fill(1.0 / FeatureDimension);
		return;
	}
	FilteredImageExampleList.NormalizeWeight(1.0);

	// Process F C V
	vecF_P_f_given_c_V.Fill(1.0);
	{
		double TotalFeatureInstanceAmount = FeatureDimension;
		for ( i_Example = 0; i_Example < FilteredImageExampleList.ExampleAmount; ++i_Example )
		{
			CWeightedClassificationExample& tExample = FilteredImageExampleList.rgExample[i_Example];
			CSourceItem& tItem = pSrcFCDS->List_Item.pElement[tExample.ExampleIndex];
			CSparseVector& tSV = tItem.FeatureList;

			TotalFeatureInstanceAmount += tItem.InstanceAmount;
			for ( i_PtrFeature = 0; i_PtrFeature < tSV.Length; ++i_PtrFeature )
			{
				i_FeatureIndex = tSV.IndexList.pElement[i_PtrFeature];
				tInstanceAmount = tSV.ValueList.pElement[i_PtrFeature];
				vecF_P_f_given_c_V.pElement[i_FeatureIndex] += tInstanceAmount;
			}
		}
		for ( i_FeatureIndex = 0; i_FeatureIndex < FeatureDimension; ++i_FeatureIndex )
			vecF_P_f_given_c_V.pElement[i_FeatureIndex] /= TotalFeatureInstanceAmount;
	}
}

void datasets_taic::CSingleClassNaiveBayesModel_TAIC::InitTextModel(
	const CSourceFeatureCountDataSet* pSrcFCDS, int Label,
	int K, int W, double Threshold_PWC )
{
	int i_Word, i_PtrFeature, i_FeatureIndex;
	double tInstanceAmount;

	if (pSrcFCDS == NULL) return;
	if (Label<0 || Label>=pSrcFCDS->Size_C) return;
	InitFeatureDimension(pSrcFCDS->Size_F);

	if (K < 0) K = 2147483647;
	this->SelectTopK = K;

	if (W<1 || W>pSrcFCDS->Size_W)
	{
		for ( W = 0; W < pSrcFCDS->Size_W; ++W )
		{
			tInstanceAmount = pSrcFCDS->GetP_w_given_c_D(W, Label);
			if (tInstanceAmount < Threshold_PWC) break;
		}

		//W = pSrcFCDS->Size_W;

		//Threshold_PWC = 0.0;
	}
	else
		Threshold_PWC = 0.0;

	this->WordDimension = W;

	// Process W C D
	vecW_P_w_given_c_D.Resize(WordDimension);
	vecW_P_w_given_c_D.Fill(0.0);
	{
		double TotalWordWeight = MINIMUM_DOUBLE_EPS_V;
		for ( i_Word = 0; i_Word < WordDimension; ++i_Word )
		{
			tInstanceAmount = pSrcFCDS->GetP_w_given_c_D(i_Word, Label);
			//tInstanceAmount -= Threshold_PWC;
			vecW_P_w_given_c_D.pElement[i_Word] = tInstanceAmount;
			TotalWordWeight += tInstanceAmount;
		}
		for ( i_Word = 0; i_Word < WordDimension; ++i_Word )
			vecW_P_w_given_c_D.pElement[i_Word] /= TotalWordWeight;
	}

	// Process F W C
	matFW_P_f_given_w_c.Resize(FeatureDimension * WordDimension);
	matFW_P_f_given_w_c.Fill(1.0);
	{
		int o, o1, o2;
		for ( i_Word = 0; i_Word < WordDimension; ++i_Word )
		{
			o1 = pSrcFCDS->LowerBound(Label, i_Word, 0);
			o2 = pSrcFCDS->UpperBound(Label, i_Word, K-1);
			double* PtrF_P_f_given_w_c = matFW_P_f_given_w_c.pElement + 0 + i_Word * FeatureDimension;
			double TotalFeatureInstanceAmount = FeatureDimension;
			for ( o = o1; o < o2; ++o )
			{
				CSourceItem& tItem = pSrcFCDS->List_Item.pElement[o];
				CSparseVector& tSV = tItem.FeatureList;
				TotalFeatureInstanceAmount += tItem.InstanceAmount;
				for ( i_PtrFeature = 0; i_PtrFeature < tSV.Length; ++i_PtrFeature )
				{
					i_FeatureIndex = tSV.IndexList.pElement[i_PtrFeature];
					tInstanceAmount = tSV.ValueList.pElement[i_PtrFeature];
					PtrF_P_f_given_w_c[i_FeatureIndex] += tInstanceAmount;
				}
			}
			for ( i_FeatureIndex = 0; i_FeatureIndex < FeatureDimension; ++i_FeatureIndex )
				PtrF_P_f_given_w_c[i_FeatureIndex] /= TotalFeatureInstanceAmount;
		}
	}

	// Process F C D
	vecF_P_f_given_c_D.Fill(0.0);
	{
		for ( i_Word = 0; i_Word < WordDimension; ++i_Word )
		{
			const double* QtrF_P_f_given_w_c = matFW_P_f_given_w_c.pElement + 0 + i_Word * FeatureDimension;
			double tP_w_given_c_D = vecW_P_w_given_c_D.pElement[i_Word];
			for ( i_FeatureIndex = 0; i_FeatureIndex < FeatureDimension; ++i_FeatureIndex )
				vecF_P_f_given_c_D.pElement[i_FeatureIndex] += QtrF_P_f_given_w_c[i_FeatureIndex] * tP_w_given_c_D;
		}
	}
}

void datasets_taic::CSingleClassNaiveBayesModel_TAIC::InitLambda( double Lambda )
{
	if (FeatureDimension < 1) return;
	if (WordDimension < 1) Lambda = MAXIMUM_DOUBLE_NUM_V;
	if (Lambda < 0.0) Lambda = 0.0;
	double wD, wV, tV, tD;
	int i_FeatureIndex;

	this->Lambda = Lambda;
	if (Lambda > MAXIMUM_DOUBLE_NUM_C)
	{
		wD = 0.0;
		wV = 1.0;
	}
	else
	{
		wD = 1.0/(1.0+Lambda);
		wV = Lambda/(1.0+Lambda);
	}

	vecF_logP_f_given_c_L.Resize(FeatureDimension);
	vecF_logP_f_given_c_L.Fill(0.0);
	double* PL = vecF_logP_f_given_c_L.pElement;
	const double* QD = vecF_P_f_given_c_D.pElement;
	const double* QV = vecF_P_f_given_c_V.pElement;
	for ( i_FeatureIndex = 0; i_FeatureIndex < FeatureDimension; ++i_FeatureIndex )
	{
		tD = (wD>MINIMUM_DOUBLE_EPS_C ? CMyMath::my_log(*QD) : 0.0);
		tV = (wV>MINIMUM_DOUBLE_EPS_C ? CMyMath::my_log(*QV) : 0.0);
		*PL += wD * tD;
		*PL += wV * tV;
		++PL; ++QD; ++QV;
	}
}

void datasets_taic::CSingleClassNaiveBayesModel_TAIC::SaveToFile( string strFN_Model ) const
{
	int i_FeatureIndex;
	char strTemp[10001];
	ofstream outFile(strFN_Model.c_str());
	sprintf_s(strTemp, "%d\n%d\t%d\t%.12e",
		FeatureDimension, SelectTopK, WordDimension, Lambda);
	outFile<<strTemp<<endl;
	for ( i_FeatureIndex = 0; i_FeatureIndex < FeatureDimension; ++i_FeatureIndex )
	{
		sprintf_s(strTemp, "%.12e\t%.12lf\t%.12lf",
			vecF_logP_f_given_c_L.pElement[i_FeatureIndex],
			vecF_P_f_given_c_V.pElement[i_FeatureIndex],
			vecF_P_f_given_c_D.pElement[i_FeatureIndex]);
		outFile<<strTemp<<endl;
	}
	outFile.close();
	outFile.clear();
}

bool datasets_taic::CSingleClassNaiveBayesModel_TAIC::LoadFromFile( string strFN_Model )
{
	int i_FeatureIndex;
	ifstream inFile(strFN_Model.c_str());
	if (!(inFile>>FeatureDimension) || (FeatureDimension<1)) return false;
	this->InitFeatureDimension(FeatureDimension);
	if (!(inFile>>SelectTopK>>WordDimension>>Lambda)) return false;
	for ( i_FeatureIndex = 0; i_FeatureIndex < FeatureDimension; ++i_FeatureIndex )
	{
		if (!(inFile
			>>vecF_logP_f_given_c_L.pElement[i_FeatureIndex]
			>>vecF_P_f_given_c_V.pElement[i_FeatureIndex]
			>>vecF_P_f_given_c_D.pElement[i_FeatureIndex]
			))
			return false;
	}
	inFile.close();
	inFile.clear();
	return true;
}

// [*] datasets_taic::CTask_TAIC

bool datasets_taic::CTask_TAIC::myInit(
	CClassDataSet* pSrcClassDataSet,
	istream& inStream)
{
	if (pSrcClassDataSet == NULL) return false;
	this->pSrcClassDataSet = pSrcClassDataSet;
	List_ClassIndex.Clear();
	if (!(inStream>>ClassAmount))
	{
		ClassAmount = 0;
		return false;
	}
	bool ret = true;
	int i, t;
	char strTemp[10001];
	for ( i = 0; i < ClassAmount; ++i )
	{
		if (!(inStream>>strTemp))
		{
			ret = false;
			break;
		}
		t = pSrcClassDataSet->GetClassIndex(strTemp);
		if (t < 0)
		{
			cout<<strTemp<<" !!!!"<<endl;
			ret = false;
		}
		List_ClassIndex.PushBack(t);
	}
	return ret;
}

void datasets_taic::CTask_TAIC::MakeClassificationDataSet(
	CSourceFeatureCountDataSet& DstDataSet_Train, int BaseImageAmountPerClass_Train,
	CSourceFeatureCountDataSet& DstDataSet_Test, int BaseImageAmountPerClass_Test,
	int MinWordIndexAllowed, int MaxWordIndexAllowed, int K) const
{
	if (ClassAmount < 1) return;
	if (1)
	{
		int tClassIndex = List_ClassIndex.pElement[0];
		const CSourceFeatureCountDataSet* pSrcFCDS = 
			pSrcClassDataSet->GetPtrFCDS(tClassIndex);
		DstDataSet_Train.InitAndClearPureImageDataSet(this->ClassAmount, pSrcFCDS->Size_F);
		DstDataSet_Test.InitAndClearPureImageDataSet(this->ClassAmount, pSrcFCDS->Size_F);
	}
	int i_Class, i_Example, tMinWordIndexAllowed, hr_Train, hr_Test;
	CWeightedClassificationExampleList tList_A;
	CWeightedClassificationExampleList tList_B;
	CWeightedClassificationExampleList tList_C;
	CWeightedClassificationExampleList tList_Train;
	CWeightedClassificationExampleList tList_Test;
	for ( i_Class = 0; i_Class < ClassAmount; ++i_Class )
	{
		int tClassIndex = List_ClassIndex.pElement[i_Class];
		const CClassInformation& tClassInformation =
			pSrcClassDataSet->List_ClassInfo.pElement[tClassIndex];
		const CSourceFeatureCountDataSet* pSrcFCDS =
			pSrcClassDataSet->GetPtrFCDS(tClassIndex);
		pSrcFCDS->MakeSingleClassImageExampleList(
			tClassInformation.In_FCDS_Label, tList_A, true, -1, -1, 0);
		tList_A.RandomSplit(tList_Train, tList_B, BaseImageAmountPerClass_Train);
		tList_B.RandomSplit(tList_Test, tList_C, BaseImageAmountPerClass_Test);
		hr_Train = hr_Test = 0;
		for ( i_Example = 0; i_Example < tList_Train.ExampleAmount; ++i_Example )
		{
			const CWeightedClassificationExample& tExample = tList_Train.rgExample[i_Example];
			if (MinWordIndexAllowed<0 && MinWordIndexAllowed<=MaxWordIndexAllowed)
				DstDataSet_Train.PushBackItem(pSrcFCDS, tExample.ExampleIndex, i_Class, -1, hr_Train++);
		}
		for ( i_Example = 0; i_Example < tList_Test.ExampleAmount; ++i_Example )
		{
			const CWeightedClassificationExample& tExample = tList_Test.rgExample[i_Example];
			DstDataSet_Test.PushBackItem(pSrcFCDS, tExample.ExampleIndex, i_Class, -1, hr_Test++);
		}

		tMinWordIndexAllowed = MinWordIndexAllowed; if (tMinWordIndexAllowed < 0) tMinWordIndexAllowed = 0;
		pSrcFCDS->MakeSingleClassImageExampleList(
			tClassInformation.In_FCDS_Label, tList_C, true, tMinWordIndexAllowed, MaxWordIndexAllowed, K);
		for ( i_Example = 0; i_Example < tList_C.ExampleAmount; ++i_Example )
		{
			const CWeightedClassificationExample& tExample = tList_C.rgExample[i_Example];
			DstDataSet_Train.PushBackItem(pSrcFCDS, tExample.ExampleIndex, i_Class, -1, hr_Train++);
		}
	}
	DstDataSet_Train.SortItemList();
	DstDataSet_Test.SortItemList();
}

void datasets_taic::CTask_TAIC::TrainImageSVM(
	CSimpleTypeArray<CSVMLightHelper::CModel>& List_SVM,
	const CSourceFeatureCountDataSet& SrcInitializedDataSet_Train) const
	//const CSourceFeatureCountDataSet& SrcInitializedDataSet_Train,
	//int MinWordIndexAllowed, int MaxWordIndexAllowed, int K) const
{
	int i_Class;
	List_SVM.Resize(ClassAmount);
	CWeightedClassificationExampleList FullList;
	SrcInitializedDataSet_Train.MakeFullImageExampleList(FullList, true, -1, -1, 0);
	C_FCDS_LabeledDataSetForClassification FCDS_DataSet;
	FCDS_DataSet.myInit(&SrcInitializedDataSet_Train);
	CDataSetForBinaryClassification bds;
	bds.SetRealDataSet(&FCDS_DataSet);

	for ( i_Class = 0; i_Class < ClassAmount; ++i_Class )
	{
		CSVMLightHelper::CModel& tSVM = List_SVM.pElement[i_Class];
		bds.SetTargetLabel(i_Class);
		CSVMLightHelper::CParameters Parameters;
		Parameters.myInit("-v 0 -c 1.0");
		tSVM.Train(&bds, FullList, Parameters);
	}
}

void datasets_taic::CTask_TAIC::TrainImageModel(
	CSimpleTypeArray<CSingleClassNaiveBayesModel_TAIC>& List_NBM,
	const CSourceFeatureCountDataSet& SrcInitializedDataSet_Train) const
	//const CSourceFeatureCountDataSet& SrcInitializedDataSet_Train,
	//int MinWordIndexAllowed, int MaxWordIndexAllowed, int K) const
{
	int i_Class;
	List_NBM.Resize(ClassAmount);
	CWeightedClassificationExampleList tList;
	for ( i_Class = 0; i_Class < ClassAmount; ++i_Class )
	{
		CSingleClassNaiveBayesModel_TAIC& tNBM = List_NBM.pElement[i_Class];
		SrcInitializedDataSet_Train.MakeSingleClassImageExampleList(
			i_Class, tList, true, -1, -1, 0);
		tNBM.InitImageModel(
			&SrcInitializedDataSet_Train, i_Class, tList, -1, -1, 0);
	}
}

void datasets_taic::CTask_TAIC::TrainTextModel(
	CSimpleTypeArray<CSingleClassNaiveBayesModel_TAIC>& List_NBM,
	int K, int W, double Threshold_PWC ) const
{
	int i_Class;
	List_NBM.Resize(ClassAmount);
	for ( i_Class = 0; i_Class < ClassAmount; ++i_Class )
	{
		CSingleClassNaiveBayesModel_TAIC& tNBM = List_NBM.pElement[i_Class];
		int tClassIndex = List_ClassIndex.pElement[i_Class];
		const CClassInformation& tClassInformation =
			pSrcClassDataSet->List_ClassInfo.pElement[tClassIndex];
		const CSourceFeatureCountDataSet* pSrcFCDS =
			pSrcClassDataSet->GetPtrFCDS(tClassIndex);
		tNBM.InitTextModel(pSrcFCDS, tClassInformation.In_FCDS_Label, K, W, Threshold_PWC);
	}
}

void datasets_taic::CTask_TAIC::TrainMixedModel(
	CSimpleTypeArray<CSingleClassNaiveBayesModel_TAIC>& List_NBM,
	double Lambda ) const
{
	int i_Class;
	List_NBM.Resize(ClassAmount);
	for ( i_Class = 0; i_Class < ClassAmount; ++i_Class )
	{
		CSingleClassNaiveBayesModel_TAIC& tNBM = List_NBM.pElement[i_Class];
		tNBM.InitLambda(Lambda);
	}
}

void datasets_taic::CTask_TAIC::Test(
	const CSimpleTypeArray<CSVMLightHelper::CModel>& List_SVM,
	const CSourceFeatureCountDataSet& SrcInitializedDataSet_Test,
	double& DstAccuracy ) const
{
	DstAccuracy = 0.50;
	int i_Example, i_Class;

	DstAccuracy = 0.0;

	C_FCDS_LabeledDataSetForClassification FCDS_DataSet;
	FCDS_DataSet.myInit(&SrcInitializedDataSet_Test);

	CWeightedClassificationExampleList tList;
	SrcInitializedDataSet_Test.MakeFullImageExampleList(tList, true, -1, -1, 0);
	tList.ComputeTotalExampleWeight();

	CSimpleTypeArray<double> PerLabelConfidence;
	PerLabelConfidence.Resize(ClassAmount);

	double rConfidence;
	int rPrediction;

	for ( i_Example = 0; i_Example < tList.ExampleAmount; ++i_Example )
	{
		CWeightedClassificationExample tExample = tList.rgExample[i_Example];
		const CSourceItem& tItem = SrcInitializedDataSet_Test.List_Item.pElement[tExample.ExampleIndex];
		PerLabelConfidence.Fill(0.0);
		for ( i_Class = 0; i_Class < ClassAmount; ++i_Class )
		{
			double& tConfidence = PerLabelConfidence.pElement[i_Class];
			CSVMLightHelper::CModel& tSVM = List_SVM.pElement[i_Class];
			tConfidence = tSVM.Classify(&FCDS_DataSet, tExample.ExampleIndex);
			if (i_Class==0 || tConfidence>rConfidence)
			{
				rConfidence = tConfidence;
				rPrediction = i_Class;
			}
		} // i_Class
		DstAccuracy += (rPrediction==tItem.Label ? tExample.Weight : 0.0);
	} // i_Example

	DstAccuracy /= tList.TotalExampleWeight;
}

void datasets_taic::CTask_TAIC::Test(
	const CSimpleTypeArray<CSingleClassNaiveBayesModel_TAIC>& List_NBM,
	const CSourceFeatureCountDataSet& SrcInitializedDataSet_Test,
	double& DstAccuracy) const
{
	DstAccuracy = 0.50;
	int i_Example, i_PtrFeature, i_FeatureIndex, i_Class;
	double tInstanceAmount;

	DstAccuracy = 0.0;

	CWeightedClassificationExampleList tList;
	SrcInitializedDataSet_Test.MakeFullImageExampleList(tList, true, -1, -1, 0);
	tList.ComputeTotalExampleWeight();

	CSimpleTypeArray<double> PerLabelConfidence;
	PerLabelConfidence.Resize(ClassAmount);

	double rConfidence;
	int rPrediction;

	for ( i_Example = 0; i_Example < tList.ExampleAmount; ++i_Example )
	{
		CWeightedClassificationExample tExample = tList.rgExample[i_Example];
		const CSourceItem& tItem = SrcInitializedDataSet_Test.List_Item.pElement[tExample.ExampleIndex];
		const CSparseVector& tSV = tItem.FeatureList;
		PerLabelConfidence.Fill(0.0);
		for ( i_Class = 0; i_Class < ClassAmount; ++i_Class )
		{
			double& tConfidence = PerLabelConfidence.pElement[i_Class];
			const CSingleClassNaiveBayesModel_TAIC& tNBM = List_NBM.pElement[i_Class];
			const double* QL = tNBM.vecF_logP_f_given_c_L.pElement;
			for ( i_PtrFeature = 0; i_PtrFeature < tSV.Length; ++i_PtrFeature )
			{
				i_FeatureIndex = tSV.IndexList.pElement[i_PtrFeature];
				tInstanceAmount = tSV.ValueList.pElement[i_PtrFeature];
				tConfidence += QL[i_FeatureIndex] * tInstanceAmount;
			}
			if (i_Class==0 || tConfidence>rConfidence)
			{
				rConfidence = tConfidence;
				rPrediction = i_Class;
			}
		} // i_Class
		DstAccuracy += (rPrediction==tItem.Label ? tExample.Weight : 0.0);
	} // i_Example

	DstAccuracy /= tList.TotalExampleWeight;
}

// [*] datasets_taic::CTaskSet_TAIC

void datasets_taic::CTaskSet_TAIC::myInit(CClassDataSet* pSrcClassDataSet, string strFN_TaskSet)
{
	ifstream inFile(strFN_TaskSet.c_str());
	TaskAmount = 0;
	List_Task.Clear();
	CTask_TAIC tTask;
	while (tTask.myInit(pSrcClassDataSet, inFile))
	{
		++TaskAmount;
		List_Task.PushBack(tTask);
	}
}

//// [*] datasets_taic::CNaiveBayesMode_TAIC
//
//datasets_taic::CNaiveBayesMode_TAIC::CNaiveBayesMode_TAIC()
//{
//	Lambda = 1.0;
//	FeatureDimension = 0;
//	LabelAmount = 0;
//	WordDimension = 0;
//}
//
//void datasets_taic::CNaiveBayesMode_TAIC::InitImageModel(
//	const CSourceFeatureCountDataSet* pSrcFCDS,
//	CWeightedClassificationExampleList& TrainImageExampleList)
//{
//	if (pSrcFCDS == NULL) return;
//
//	int i_example, i_feature, i_label, j_FeatureIndex;
//	int tFeatureIndex;
//	double tInstanceAmount;
//
//	this->FeatureDimension = pSrcFCDS->Size_F;
//	this->LabelAmount = pSrcFCDS->Size_C;
//
//	CWeightedClassificationExampleList FilteredImageExampleList;
//	FilteredImageExampleList.Clear();
//	for ( i_example = 0; i_example < TrainImageExampleList.ExampleAmount; ++i_example )
//	{
//		CWeightedClassificationExample& tExample = TrainImageExampleList.rgExample[i_example];
//		CSourceItem& tItem = pSrcFCDS->List_Item.pElement[tExample.ExampleIndex];
//		if (tItem.WordIndex >= 0) continue;
//		FilteredImageExampleList.PushBack(tExample);
//	}
//	if (FilteredImageExampleList.TotalExampleWeight < MINIMUM_DOUBLE_EPS_C)
//	{
//		vecC_P_c_given_V.Resize(LabelAmount);
//		matFC_P_f_given_c_V.Resize(FeatureDimension * LabelAmount);
//		vecC_P_c_given_V.Fill(1.0 / LabelAmount);
//		matFC_P_f_given_c_V.Fill(1.0 / FeatureDimension);
//		return;
//	}
//	FilteredImageExampleList.NormalizeWeight(1.0);
//
//	// Process F C V
//	vecC_P_c_given_V.Resize(LabelAmount);
//	matFC_P_f_given_c_V.Resize(FeatureDimension * LabelAmount);
//	{
//		vecC_P_c_given_V.Fill(0.0);
//		matFC_P_f_given_c_V.Fill(1.0);
//
//		CSimpleTypeArray<double> vecC_CountFeature_c_V;
//		vecC_CountFeature_c_V.Resize(LabelAmount);
//		vecC_CountFeature_c_V.Fill(FeatureDimension);
//		for ( i_example = 0; i_example < FilteredImageExampleList.ExampleAmount; ++i_example )
//		{
//			CWeightedClassificationExample& tExample = FilteredImageExampleList.rgExample[i_example];
//			CSourceItem& tItem = pSrcFCDS->List_Item.pElement[tExample.ExampleIndex];
//			CSparseVector& tSV = tItem.FeatureList;
//
//			vecC_P_c_given_V.pElement[tItem.Label] += tExample.Weight;
//
//			vecC_CountFeature_c_V.pElement[tItem.Label] += tItem.InstanceAmount;
//			for ( i_feature = 0; i_feature < tSV.Length; ++i_feature )
//			{
//				tFeatureIndex = tSV.IndexList.pElement[i_feature];
//				tInstanceAmount = tSV.ValueList.pElement[i_feature];
//				matFC_P_f_given_c_V.pElement[tFeatureIndex + tItem.Label * FeatureDimension] += tInstanceAmount;
//				//vecC_CountFeature_c_V.pElement[tItem.Label] += tInstanceAmount;
//			}
//		}
//		for ( i_label = 0; i_label < LabelAmount; ++i_label )
//		{
//			tInstanceAmount = vecC_CountFeature_c_V.pElement[i_label];
//			double* PtrF_P_f_given_c_V = matFC_P_f_given_c_V.pElement + 0 + i_label * FeatureDimension;
//			for ( j_FeatureIndex = 0; j_FeatureIndex < FeatureDimension; ++j_FeatureIndex )
//				PtrF_P_f_given_c_V[j_FeatureIndex] /= tInstanceAmount;
//		}
//	}
//
//	//SetLambda(Lambda);
//}
//
//void datasets_taic::CNaiveBayesMode_TAIC::InitTextModel(
//	const CSourceFeatureCountDataSet* pSrcFCDS,
//	int K, int W)
//{
//	if (pSrcFCDS == NULL) return;
//	if (K < 0) K = 2147483647;
//	if (W < 0) W = pSrcFCDS->Size_W;
//
//	int i_feature, i_word, i_label, j_FeatureIndex;
//	int tFeatureIndex;
//	double tInstanceAmount;
//
//	this->FeatureDimension = pSrcFCDS->Size_F;
//	this->WordDimension = (W>pSrcFCDS->Size_W ? pSrcFCDS->Size_W : W);
//	this->LabelAmount = pSrcFCDS->Size_C;
//
//	// Process W C D
//	vecC_P_c_given_D.Resize(LabelAmount);
//	matWC_P_w_given_c_D.Resize(WordDimension * LabelAmount);
//	{
//		vecC_P_c_given_D.Fill(1.0 / LabelAmount);
//
//		matWC_P_w_given_c_D.Fill(0.0);
//		double tt, divider;
//		for ( i_label = 0; i_label < LabelAmount; ++i_label )
//		{
//			double* PtrW_P_w_given_c_D = matWC_P_w_given_c_D.pElement + 0 + i_label * WordDimension;
//			divider = MINIMUM_DOUBLE_EPS_V;
//			for ( i_word = 0; i_word < WordDimension; ++i_word )
//			{
//				tt = pSrcFCDS->GetP_w_given_c_D(i_word, i_label);
//				PtrW_P_w_given_c_D[i_word] = tt;
//				divider += tt;
//			}
//			for ( i_word = 0; i_word < WordDimension; ++i_word )
//				PtrW_P_w_given_c_D[i_word] /= divider;
//		}
//	}
//
//	// Process F W C
//	matFWC_P_f_given_w_c.Resize(FeatureDimension * WordDimension * LabelAmount);
//	{
//		int o, o1, o2;
//		matFWC_P_f_given_w_c.Fill(1.0);
//		for ( i_label = 0; i_label < LabelAmount; ++i_label ) for ( i_word = 0; i_word < WordDimension; ++i_word )
//		{
//			o1 = pSrcFCDS->LowerBound(i_label, i_word, 0);
//			o2 = pSrcFCDS->UpperBound(i_label, i_word, K-1);
//			double* PtrF_P_f_given_w_c = matFWC_P_f_given_w_c.pElement
//				+ 0 + (i_word + i_label * WordDimension) * FeatureDimension;
//			double divider = FeatureDimension;
//			for ( o = o1; o < o2; ++o )
//			{
//				CSourceItem& tItem = pSrcFCDS->List_Item.pElement[o];
//				CSparseVector& tSV = tItem.FeatureList;
//				divider += tItem.InstanceAmount;
//				for ( i_feature = 0; i_feature < tSV.Length; ++i_feature )
//				{
//					tFeatureIndex = tSV.IndexList.pElement[i_feature];
//					tInstanceAmount = tSV.ValueList.pElement[i_feature];
//					PtrF_P_f_given_w_c[tFeatureIndex] += tInstanceAmount;					
//					//divider += tInstanceAmount;
//				}
//			}
//			for ( j_FeatureIndex = 0; j_FeatureIndex < FeatureDimension; ++j_FeatureIndex )
//				PtrF_P_f_given_w_c[j_FeatureIndex] /= divider;
//		}
//	}
//
//	// Process F C D
//	matFC_P_f_given_c_D.Resize(FeatureDimension * LabelAmount);
//	{
//		matFC_P_f_given_c_D.Fill(0.0);
//		double tP_w_given_c_D;
//		for ( i_label = 0; i_label < LabelAmount; ++i_label )
//		{
//			double* PtrF_P_f_given_c_D = matFC_P_f_given_c_D.pElement + 0 + i_label * FeatureDimension;
//			for ( i_word = 0; i_word < WordDimension; ++i_word )
//			{
//				const double* QtrF_P_f_given_w_c = matFWC_P_f_given_w_c.pElement
//					+ 0 + (i_word + i_label * WordDimension) * FeatureDimension;
//				tP_w_given_c_D = matWC_P_w_given_c_D.pElement[i_word + i_label * WordDimension];
//				for ( j_FeatureIndex = 0; j_FeatureIndex < FeatureDimension; ++j_FeatureIndex )
//					PtrF_P_f_given_c_D[j_FeatureIndex] += QtrF_P_f_given_w_c[j_FeatureIndex] * tP_w_given_c_D;
//			}
//		}
//	}
//
//	//SetLambda(Lambda);
//}
//
//void datasets_taic::CNaiveBayesMode_TAIC::SetLambda( double Lambda )
//{
//	if (FeatureDimension<1 || LabelAmount<1) return;
//	if (WordDimension<1) Lambda = MAXIMUM_DOUBLE_NUM_V;
//	if (Lambda<0.0) Lambda = 0.0;
//	double wD, wV, tV, tD;
//	int i_label, i_feature;
//
//	this->Lambda = Lambda;
//	wD = 1.0/(1.0+Lambda);
//	wV = Lambda/(1.0+Lambda);
//
//	vecC_logP_c_given_L.Resize(LabelAmount);
//	vecC_logP_c_given_L.Fill(0.0);
//	matFC_logP_f_given_c_L.Resize(FeatureDimension * LabelAmount);
//	matFC_logP_f_given_c_L.Fill(0.0);
//	for ( i_label = 0; i_label < LabelAmount; ++i_label )
//	{
//		vecC_logP_c_given_L.pElement[i_label] += wV * CMyMath::my_log(vecC_P_c_given_V.pElement[i_label]);
//		vecC_logP_c_given_L.pElement[i_label] += wD * CMyMath::my_log(vecC_P_c_given_D.pElement[i_label]);
//		double* PL = matFC_logP_f_given_c_L.pElement + 0 + i_label * FeatureDimension;
//		const double* QD = matFC_P_f_given_c_D.pElement + 0 + i_label * FeatureDimension;
//		const double* QV = matFC_P_f_given_c_V.pElement + 0 + i_label * FeatureDimension;
//		for ( i_feature = 0; i_feature < FeatureDimension; ++i_feature )
//		{
//			tD = CMyMath::my_log(*QD);
//			tV = CMyMath::my_log(*QV);
//			*PL += wD * tD;
//			*PL += wV * tV;
//			++PL; ++QD; ++QV;
//		}
//	}
//}
//
//double datasets_taic::CNaiveBayesMode_TAIC::GetP_f_given_c_V( int FeatureIndex, int Label ) const
//{
//	if (FeatureIndex<0 || FeatureIndex>=FeatureDimension) return 0.0;
//	if (Label<0 || Label>=LabelAmount) return 0.0;
//	return matFC_P_f_given_c_V.pElement[FeatureIndex + Label * FeatureDimension];
//}
//
//double datasets_taic::CNaiveBayesMode_TAIC::GetP_f_given_c_D( int FeatureIndex, int Label ) const
//{
//	if (FeatureIndex<0 || FeatureIndex>=FeatureDimension) return 0.0;
//	if (Label<0 || Label>=LabelAmount) return 0.0;
//	return matFC_P_f_given_c_D.pElement[FeatureIndex + Label * FeatureDimension];
//}
//
//double datasets_taic::CNaiveBayesMode_TAIC::GetLogP_f_given_c_L( int FeatureIndex, int Label ) const
//{
//	if (FeatureIndex<0 || FeatureIndex>=FeatureDimension) return 0.0;
//	if (Label<0 || Label>=LabelAmount) return 0.0;
//	return matFC_logP_f_given_c_L.pElement[FeatureIndex + Label * FeatureDimension];
//}
//
//void datasets_taic::CNaiveBayesMode_TAIC::Test(
//	const CSourceFeatureCountDataSet* pSrcFCDS,
//	CWeightedClassificationExampleList& TestExampleList,
//	double& DstAccuracy)
//{
//	DstAccuracy = 0.50;
//	if (pSrcFCDS==NULL || TestExampleList.ExampleAmount<1) return;
//	int i_example, i_feature, i_label;
//	int tFeatureIndex;
//	double tInstanceAmount;
//
//	TestExampleList.ComputeTotalExampleWeight();
//	DstAccuracy = 0.0;
//
//	CSimpleTypeArray<double> PerLabelConfidence;
//	PerLabelConfidence.Resize(LabelAmount);
//
//	double rConfidence;
//	int rPrediction;
//	for ( i_example = 0; i_example < TestExampleList.ExampleAmount; ++i_example )
//	{
//		const CWeightedClassificationExample& tExample = TestExampleList.rgExample[i_example];
//		const CSourceItem& tItem = pSrcFCDS->List_Item.pElement[tExample.ExampleIndex];
//		const CSparseVector& tSV = tItem.FeatureList;
//		PerLabelConfidence.Clear(); PerLabelConfidence.PushBack(vecC_logP_c_given_L);
//		for ( i_label = 0; i_label < LabelAmount; ++i_label )
//		{
//			double& DstConfidence = PerLabelConfidence.pElement[i_label];
//			const double* QL = matFC_logP_f_given_c_L.pElement + 0 + i_label * FeatureDimension;
//			for ( i_feature = 0; i_feature < tSV.Length; ++i_feature )
//			{
//				tFeatureIndex = tSV.IndexList.pElement[i_feature];
//				tInstanceAmount = tSV.ValueList.pElement[i_feature];
//				//CARE
//				if (0)
//					tInstanceAmount /= tItem.InstanceAmount;
//				DstConfidence += tInstanceAmount * QL[tFeatureIndex];
//			}
//			if (i_label==0 || DstConfidence>rConfidence)
//			{
//				rConfidence = DstConfidence;
//				rPrediction = i_label;
//			}
//		}
//		DstAccuracy += (rPrediction==tItem.Label ? tExample.Weight : 0.0);
//	}
//	DstAccuracy /= TestExampleList.TotalExampleWeight;
//}

